using PK.Broadcaster;
using PKGames.MiniGames.Common.Scripts;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using VoxelEngine;
using VoxelEngine.UI;
using VoxelGame.Character;

namespace PKGames.MiniGames.VoxelGame.UI.GameUI.Scripts.GamePanel
{
	public class BlockSelectionUiController : UiStateController<BlockSelectionUiState>, IMessageSubscriber<ToolChangedMessage>, IMessageSubscriber<BlockChangedMessage>, IMessageSubscriber<WorldCreationFinishedMessage>
	{
		[SerializeField]
		private RectTransform _blockSelectionRectTransform;

		[SerializeField]
		private GameObject _listParent;

		[SerializeField]
		private GameObject _blockListElementPrefab;

		[SerializeField]
		private CanvasGroup _listCanvasGroup;

		[SerializeField]
		private ListScrollAnimation _listScrollAnimation;

		private readonly List<BlockUiCell> _blockUiCellList = new List<BlockUiCell>();

		private float _startHeight;

		private float _currentAnimationPercentage;

		private const float AnimationTime = 0.2f;

		[CompilerGenerated]
		private static Action<BlockType> _003C_003Ef__mg_0024cache0;

		private void Awake()
		{
			_startHeight = _blockSelectionRectTransform.rect.height;
			MessageBroadcaster.Instance.Subscribe<ToolChangedMessage>(this);
			MessageBroadcaster.Instance.Subscribe<BlockChangedMessage>(this);
		}

		private void OnDestroy()
		{
			MessageBroadcaster.Instance.Unsubscribe<ToolChangedMessage>(this);
			MessageBroadcaster.Instance.Unsubscribe<BlockChangedMessage>(this);
		}

		public void Setup(BlockSelectionData blockSelectionData)
		{
			PopulateBlockList(blockSelectionData);
			StartCoroutine(_listScrollAnimation.Setup());
		}

		private void PopulateBlockList(BlockSelectionData blockSelectionData)
		{
			foreach (BlockSelectionItem listOfItem in blockSelectionData.ListOfItems)
			{
				if (listOfItem.Type != BlockType.Unknown)
				{
					GameObject gameObject = UnityEngine.Object.Instantiate(_blockListElementPrefab, _listParent.transform);
					BlockUiCell componentInChildren = gameObject.GetComponentInChildren<BlockUiCell>();
					_blockUiCellList.Add(componentInChildren);
					componentInChildren.Setup(listOfItem, OnBlockSelected);
				}
			}
		}

		private static void OnBlockSelected(BlockType blockType)
		{
			MessageBroadcaster.Instance.BroadcastMessage(new ChangeBlockMessage(blockType));
		}

		protected override bool CanChangeToNextState(BlockSelectionUiState nextState)
		{
			switch (base.UiState)
			{
			case BlockSelectionUiState.Shown:
				return nextState == BlockSelectionUiState.ShownToHiddenTransition;
			case BlockSelectionUiState.Hidden:
				return nextState == BlockSelectionUiState.HiddenToShownTransition;
			case BlockSelectionUiState.HiddenToShownTransition:
				return nextState == BlockSelectionUiState.Shown || nextState == BlockSelectionUiState.ShownToHiddenTransition;
			case BlockSelectionUiState.ShownToHiddenTransition:
				return nextState == BlockSelectionUiState.Hidden || nextState == BlockSelectionUiState.HiddenToShownTransition;
			default:
				return false;
			}
		}

		protected override void UpdateUiAccordingToState(BlockSelectionUiState nextState)
		{
			switch (nextState)
			{
			case BlockSelectionUiState.Shown:
				OnShownState();
				break;
			case BlockSelectionUiState.Hidden:
				OnHiddenState();
				break;
			case BlockSelectionUiState.HiddenToShownTransition:
				OnHiddenToShownState();
				break;
			case BlockSelectionUiState.ShownToHiddenTransition:
				OnShownToHiddenState();
				break;
			}
		}

		private void OnShownState()
		{
			_listCanvasGroup.interactable = true;
			StopCoroutine("AnimateToolSelectionUi");
			SetAnimationClip(1f);
		}

		private void SetAnimationClip(float percentage)
		{
			_currentAnimationPercentage = percentage;
			RectTransform blockSelectionRectTransform = _blockSelectionRectTransform;
			Vector2 offsetMin = _blockSelectionRectTransform.offsetMin;
			blockSelectionRectTransform.offsetMin = new Vector2(offsetMin.x, Mathf.Lerp(0f, 0f - _startHeight, percentage));
			RectTransform blockSelectionRectTransform2 = _blockSelectionRectTransform;
			Vector2 offsetMax = _blockSelectionRectTransform.offsetMax;
			blockSelectionRectTransform2.offsetMax = new Vector2(offsetMax.x, Mathf.Lerp(_startHeight, 0f, percentage));
		}

		private void OnHiddenState()
		{
			_listCanvasGroup.interactable = false;
			StopCoroutine("AnimateToolSelectionUi");
			SetAnimationClip(0f);
		}

		private void OnHiddenToShownState()
		{
			_listCanvasGroup.interactable = false;
			StopCoroutine("AnimateToolSelectionUi");
			StartCoroutine(AnimateToolSelectionUi(_currentAnimationPercentage, 1f, delegate
			{
				TryChangingToNextState(BlockSelectionUiState.Shown);
			}));
		}

		private IEnumerator AnimateToolSelectionUi(float fromPercentage, float toPercentage, Action onFinish)
		{
			AnimationCurve animationCurve = AnimationCurve.EaseInOut(0f, fromPercentage, 0.2f * Mathf.Abs(toPercentage - fromPercentage), toPercentage);
			for (float time = 0f; time < 0.2f; time += Time.deltaTime)
			{
				SetAnimationClip(animationCurve.Evaluate(time));
				yield return null;
			}
			onFinish.Fire();
		}

		private void OnShownToHiddenState()
		{
			_listCanvasGroup.interactable = false;
			StopCoroutine("AnimateToolSelectionUi");
			StartCoroutine(AnimateToolSelectionUi(_currentAnimationPercentage, 0f, delegate
			{
				TryChangingToNextState(BlockSelectionUiState.Hidden);
			}));
		}

		public void OnMessageReceived(ToolChangedMessage message)
		{
			TryChangingToNextState((message.ToolTypeSelected == CharacterToolsController.ToolData.Tools.Pickaxe) ? BlockSelectionUiState.HiddenToShownTransition : BlockSelectionUiState.ShownToHiddenTransition);
		}

		public void OnMessageReceived(BlockChangedMessage message)
		{
			foreach (BlockUiCell blockUiCell in _blockUiCellList)
			{
				blockUiCell.UpdateSelection(message.BlockTypeSelected);
			}
		}

		public void OnMessageReceived(WorldCreationFinishedMessage message)
		{
			PlayBlockListStartAnimation();
		}

		private void PlayBlockListStartAnimation()
		{
			StartCoroutine(PlayBlockListStartAnimationAsync());
		}

		private IEnumerator PlayBlockListStartAnimationAsync()
		{
			_listCanvasGroup.interactable = false;
			yield return _listScrollAnimation.AnimateListIfPossible();
			_listCanvasGroup.interactable = (base.UiState == BlockSelectionUiState.Shown);
		}
	}
}
